import * as THREE from '../../build/three.module.js';
import Stats from '../../jsm/libs/stats.module.js';

let halfWidth = innerWidth / 2;
let halfHeight = innerHeight / 2;
let mouseX = 0, mouseY = 0;

const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);

const k = innerWidth / innerHeight,
      s = 25,
      camera = new THREE.PerspectiveCamera(s, k, .1, 10000);
camera.position.z = 1800;

// 光源
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(0, 0, 1);
scene.add(light);

// 用 CanvasTexture 绘制阴影
const canvas = document.createElement('canvas');
canvas.width = 128;
canvas.height = 128;
const context = canvas.getContext('2d');
const radial = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
radial.addColorStop(.1, 'rgba(210, 210, 210, 1)');
radial.addColorStop(1, 'rgba(255, 255, 255, 1)');
context.fillStyle = radial;
context.fillRect(0, 0, canvas.width, canvas.height);

const canvasTexture = new THREE.CanvasTexture(canvas);
const stl = new THREE.PlaneBufferGeometry(300, 300, 1, 1);
const mtl = new THREE.MeshBasicMaterial({ map: canvasTexture });

let shadow = new THREE.Mesh(stl, mtl);
shadow.position.y = -250;
shadow.rotation.x = -Math.PI / 2;
scene.add(shadow);

shadow = new THREE.Mesh(stl, mtl);
shadow.position.y = -250;
shadow.position.x = -400;
shadow.rotation.x = -Math.PI / 2;
scene.add(shadow);

shadow = new THREE.Mesh(stl, mtl);
shadow.position.y = -250;
shadow.position.x = 400;
shadow.rotation.x = -Math.PI / 2;
scene.add(shadow);

// 创建多面体几何模型
const radius = 200;
const stlIcosahedron = new THREE.IcosahedronBufferGeometry(radius, 1);
const count = stlIcosahedron.attributes.position.count;
stlIcosahedron.setAttribute('color', new THREE.BufferAttribute( new Float32Array( count * 3 ), 3 ))
const stlIcosahedron2 = stlIcosahedron.clone();
const stlIcosahedron3 = stlIcosahedron.clone();

// 顶点着色
const color = new THREE.Color();
const p1 = stlIcosahedron.attributes.position;
const p2 = stlIcosahedron2.attributes.position;
const p3 = stlIcosahedron3.attributes.position;
const color1 = stlIcosahedron.attributes.color;
const color2 = stlIcosahedron2.attributes.color;
const color3 = stlIcosahedron3.attributes.color;

for(let i = 0; i < count; i += 1) {
  color.setHSL((p1.getY(i) / radius + 1) / 2, 1, .5);
  color1.setXYZ(i, color.r, color.g, color.b);
  
  color.setHSL(0, (p2.getY(i) / radius + 1) / 2, .5);
  color2.setXYZ(i, color.r, color.g, color.b);
  
  color.setRGB(1, .8 - (p3.getY(i) / radius + 1) / 2, 0);
  color3.setXYZ(i, color.r, color.g, color.b);
}

// 设置材质
const mtlPhong = new THREE.MeshPhongMaterial({
  color: 0xffffff,
  flatShading: true,
  vertexColors: THREE.VertexColors,
  shininess: 0
})
const mtlWireframe = new THREE.MeshBasicMaterial({ color:0x000000, wireframe: true, transparent: true });

// 床架网格对象
let mesh3 = new THREE.Mesh(stlIcosahedron, mtlPhong);
let wireframe3 = new THREE.Mesh(stlIcosahedron, mtlWireframe);
mesh3.add(wireframe3);
mesh3.position.x = -400;
mesh3.rotation.x = -Math.PI / 2;
scene.add(mesh3);

let mesh1 = new THREE.Mesh(stlIcosahedron2, mtlPhong);
let wireframe1 = new THREE.Mesh(stlIcosahedron2, mtlWireframe);
mesh1.add(wireframe1);
mesh1.position.x = 400;
scene.add(mesh1);

let mesh2 = new THREE.Mesh(stlIcosahedron3, mtlPhong);
let wireframe2 = new THREE.Mesh(stlIcosahedron3, mtlWireframe);
mesh2.add(wireframe2);
scene.add(mesh2);

// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

// 交互控制
const handleWindowResize = () => {
  halfWidth = innerWidth / 2;
  halfHeight = innerHeight / 2;

  camera.aspect = innerWidth / innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize(innerWidth, innerHeight);
}
const handleWindowMouseMove = (e) => {
  mouseX = e.clientX - halfWidth;
  mouseY = e.clientY - halfHeight;
}
document.addEventListener('resize', handleWindowResize);
document.addEventListener('mousemove', handleWindowMouseMove);

// 监控组件
const stats = new Stats();
document.body.appendChild(stats.dom);

// 渲染函数
const render = () => {
  camera.position.x += (mouseX - camera.position.x) * .05;
  camera.position.y += (- mouseY - camera.position.y) * .05;

  camera.lookAt(scene.position);

  renderer.render(scene, camera);
}

(function animation() {
  requestAnimationFrame(animation);
  stats.update();

  render();
})();